package com.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;



public class FileUtil {
	private static final Log log = LogFactory.getLog(FileUtil.class);//日志
	
	/**
	 * 文件寫入硬盤
	 * 
	 * @param saveDir
	 *            地址
	 * @param fileName
	 *            文件名
	 * @param data
	 */
	public static void saveFile(String saveDir, String fileName, byte[] data)
			throws Exception {
		BufferedOutputStream fout = null;
		ByteArrayInputStream in = new ByteArrayInputStream(data);
		FileOutputStream out = null;
		try {
			File f = new File(saveDir);
			if (!f.exists()) {
				if (!f.mkdirs()) {
					log.error("檔夾創建失敗....");
					throw new Exception("檔夾創建失敗");
				}
			}
			out = new FileOutputStream(new File(f, fileName));
			byte[] b = new byte[1024 * 10];
			fout = new BufferedOutputStream(out);
			while (in.read(b) > 0) {
				out.write(b);
			}
			out.flush();
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			if (out != null) {
				out.close();
			}
			if (in != null) {
				in.close();
			}
			if (fout != null) {
				fout.close();
			}
		}
	}
	

	/**
	 * 下載（从服务器上下载现程的文件）
	 * @param request
	 * @param response
	 * @param path 路径Z:\PowerTest\
	 * @param fileName 文件名 ExampleFile/UserProfileExample.xls
	 * @throws Exception
	 * @return loadFlag ---true 下載成功， false  下載失敗
	 */
	public static boolean download(HttpServletRequest request, HttpServletResponse response, String path, String fileName) throws Exception{  
		boolean loadFlag = true; //下載成功標志位
		File file = null;
		InputStream in = null; // 輸入流
		OutputStream out = null; // 輸出流
		//在下載附件之前設置響應類型和頭部文件
		response.setContentType("application/x-msdownload");
		response.setHeader("Content-disposition", "attachment;filename="+ URLEncoder.encode(PageUtil.subLastStr(fileName, "/"),"UTF-8"));		
		try{
			file = new File(path + fileName); //取得文件對像
//			從下載附件創建輸入流，并向請求獲取并寫入（客戶端或網絡）輸出流
			in = new BufferedInputStream(new FileInputStream(file));
			out = response.getOutputStream();
			int readSize = 1024 * 10; //讀取大小
			int length = 0; //讀取剩余大小
			byte[] readByte = new byte[readSize];
			while ((length = in.read(readByte, 0, readSize)) != -1) {
				out.write(readByte, 0, length);
			}
			out.flush();
		}catch(Exception e){
			loadFlag = false;
			e.printStackTrace();
		}finally{
			if(in!=null || out!=null ){
				try {
					in.close();
					out.close();
				} catch (IOException e) {
					loadFlag = false;
					e.printStackTrace();
				}	
			}
		}
		return loadFlag;
	}
	
	/**
	 * 遍歷文件，取得文件名
	 * @param filePath
	 * @return
	 */
	public static Map<String , List<String>> ergodicFile(String filePath){
		//ArrayList pathList = new ArrayList();
		LinkedList<File> list = new LinkedList<File>(); 
		File dir = new File(filePath);   
		Map<String , List<String>> map = new HashMap<String , List<String>>();//分类路径变量jpg,xml
		String pathTemp = "";//临时绝对路径变量()
		String suffix ="";
		if(!dir.exists()){
			return new HashMap<String , List<String>>();
		}
		File file[] = dir.listFiles();   
		for (int i = 0; i < file.length; i++) {  
		     if (file[i].isDirectory()){  
		         list.add(file[i]);    
		     }else{  
		    	 pathTemp = file[i].getAbsolutePath();
		    	 suffix = pathTemp.substring(pathTemp.lastIndexOf(".")+1);
		    	 List<String> absolutePathList = null;
		    	 if(map.get(suffix) == null){//目前沒有這個後綴存入map中
		    		 absolutePathList = new ArrayList<String>();//路徑
		    		 absolutePathList.add(pathTemp);
		    		 map.put(suffix, absolutePathList);
		    	 }else{
		    		 absolutePathList = map.get(suffix);
		    		 absolutePathList.add(pathTemp);
		    	 }
		     }
		} 
		File tmp;     
		while (!list.isEmpty()) {    
		    tmp = (File)list.removeFirst();   
		    if (tmp.isDirectory()) {   
		       file = tmp.listFiles(); 
		       if (file == null) continue;  
		       for (int i = 0; i < file.length; i++) { 
		            if (file[i].isDirectory()) {
		            	list.add(file[i]);  
		            }else{
		            	 pathTemp = file[i].getAbsolutePath();
				    	 suffix = pathTemp.substring(pathTemp.lastIndexOf(".")+1);
				    	 List<String> absolutePathList = null;
				    	 if(map.get(suffix) == null){//目前沒有這個後綴存入map中
				    		 absolutePathList = new ArrayList<String>();//路徑
				    		 absolutePathList.add(pathTemp);
				    		 map.put(suffix, absolutePathList);
				    	 }else{
				    		 absolutePathList = map.get(suffix);
				    		 absolutePathList.add(pathTemp);
				    	 }
		            } 
		       }
		    }else {  
		    	 pathTemp = tmp.getAbsolutePath();
		    	 suffix = pathTemp.substring(pathTemp.lastIndexOf(".")+1);
		    	 List<String> absolutePathList = null;
		    	 if(map.get(suffix) == null){//目前沒有這個後綴存入map中
		    		 absolutePathList = new ArrayList<String>();//路徑
		    		 absolutePathList.add(pathTemp);
		    		 map.put(suffix, absolutePathList);
		    	 }else{
		    		 absolutePathList = map.get(suffix);
		    		 absolutePathList.add(pathTemp);
		    	 }
		    }        
		} 
		return map;
 
	}
	

	
	
	
	public static final void main(String arg[]) throws Exception{
		
   }
	
	/**
	 * 遍歷文件并拷贝目录文件，取得文件名
	 * @param filePath
	 * @param pathOfAferCopy 拷贝后的文件存入位置
	 * @param copyFlag 是拷贝
	 * @return
	 * @throws Exception 
	 */
	public static void ergodicAndCopyFile(String lastDirName, String filePath, String pathOfAferCopy, Date modifyDate, boolean hiddenFile, String[] magazines) throws Exception{
		LinkedList list = new LinkedList(); 
		File dir = new File(filePath);   
		File file[] = dir.listFiles();  
		String absolutePath = "";//文件或目录的绝对路径   变量
		long currentFileModifyTime = 0; //文件的修改时间 变量
		for (int i = 0; i < file.length; i++) {  
		     if (file[i].isDirectory()){  //目录处理方式
			    		if(file[i].isHidden() && !hiddenFile){//隐藏文件
			    			 continue;
			    		}
				        list.add(file[i]);

		     }else{  //文件处理方式
		    	 currentFileModifyTime = file[i].lastModified();//要测这个时间是不是
		    	
		    	 if( modifyDate.getTime() < currentFileModifyTime ){//文件的修改时间要大于给定的时间
			    		if(file[i].isHidden() && !hiddenFile){//隐藏文件
			    			 continue;
			    		}
			    		
			    		absolutePath = file[i].getAbsolutePath();
			    		if(magazines !=null && magazines.length != 0 ){//后缀处理
			    			int idex = absolutePath.lastIndexOf(".");
			    			String sufi = absolutePath.substring(idex+1);
			    			for (int j = 0; j < magazines.length; j++) {
								if(sufi.trim().equals(magazines[j])){
									handleUpDate(file[i],filePath,pathOfAferCopy);
									continue;
								}
							}
			    		}else{//處理全部數據
			    			handleUpDate(file[i],filePath,pathOfAferCopy);
			    		}
		    	 }
		     }
		} 
		File tmp;     
		while (!list.isEmpty()) {    
		    tmp = (File)list.removeFirst();   
		    System.out.println(tmp.getAbsolutePath()+"--------------");
		    if (tmp.isDirectory()) {   
		       file = tmp.listFiles(); 
		       if (file == null) continue;  
		       for (int i = 0; i < file.length; i++) { 
		            if (file[i].isDirectory()) {//目录处理方式
					    	if(file[i].isHidden() && !hiddenFile){//隐藏文件
					    		continue;
					    	}
						    list.add(file[i]);
		            }else{
		            	 currentFileModifyTime = file[i].lastModified();//要测这个时间是不是
				    	 if( modifyDate.getTime() < currentFileModifyTime ){//文件的修改时间要大于给定的时间
					    		if(file[i].isHidden() && !hiddenFile){//隐藏文件
					    			 continue;
					    		}
					    		absolutePath = file[i].getAbsolutePath();
					    		if(magazines !=null && magazines.length != 0 ){
					    			int idex = absolutePath.lastIndexOf(".");
					    			String sufi = absolutePath.substring(idex+1);
					    			for (int j = 0; j < magazines.length; j++) {
										if(sufi.trim().equals(magazines[j])){
											handleUpDate(file[i],filePath,pathOfAferCopy);
											continue;
										}
									}
					    		}else{//處理全部數據
					    			handleUpDate(file[i],filePath,pathOfAferCopy);
					    		}
				    	 }
		            } 
		       }
		    }else {  //是文件
		    	currentFileModifyTime = tmp.lastModified();//要测这个时间是不是
		    	 if( modifyDate.getTime() < currentFileModifyTime ){//文件的修改时间要大于给定的时间
			    		if(tmp.isHidden() && !hiddenFile){//隐藏文件
			    			 continue;
			    		}
			    		absolutePath = tmp.getAbsolutePath();
			    		if(magazines !=null && magazines.length != 0 ){
			    			int idex = absolutePath.lastIndexOf(".");
			    			String sufi = absolutePath.substring(idex+1);
			    			for (int j = 0; j < magazines.length; j++) {
								if(sufi.trim().equals(magazines[j])){
									handleUpDate(tmp,filePath,pathOfAferCopy);
									continue;
								}
							}
			    		}else{//處理全部數據
			    			handleUpDate(tmp,filePath,pathOfAferCopy);
			    		}
		    	 }       
		    }        
		} 
		
	}
	/**
	 * 對上面代碼簡化
	 * @param file
	 * @param oldfilePath原始路徑
	 * @param toFilePath目標路徑
	 */
	public static void handleUpDate(File file,String oldfilePath,String toFilePath){
		String fileName = file.getName();	    
		InputStream is;
		try {
			is = new  FileInputStream(file);
			int startIdext = oldfilePath.lastIndexOf("\\");//原始路徑   	
			int endIndex = file.getAbsolutePath().lastIndexOf("\\");
			String subAfterContent = subString(file.getAbsolutePath() ,startIdext, endIndex);

			saveFile4(toFilePath +  subAfterContent,fileName,is);
		} catch (Exception e) {
			System.out.println("路徑處理報錯");
			e.printStackTrace();
		}
		
	}
	
	/**
	 * 文件寫入硬盤
	 * 
	 * @param saveDir
	 *            地址
	 * @param fileName
	 *            文件名
	 * @param data
	 */
	public static void saveFile4(String saveDir, String fileName, InputStream inputStream)
			throws Exception {		
		BufferedOutputStream fout = null;
		InputStream in = inputStream;
		OutputStream out = null;
		try {
			File f = new File(saveDir);
			if (!f.exists()) {
				if (!f.mkdirs()) {
					log.error("檔夾創建失敗....");
					throw new Exception("檔夾創建失敗");
				}
			}
			
		//	out =new BufferedWriter(new  FileWriter(new File(f+"\\"+fileName),  true)) ;// new FileOutputStream(new File(f, fileName));
			out = new FileOutputStream(f+"\\"+fileName);
		//	String s="";
//			 while((s=in.readLine())!=null){
//				 out.write(s);
//				 out.newLine();
//			}
			int b ;
			 while((b=in.read())!=-1){
			      out.write(b);
			 }
			out.flush();
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			if (out != null) {
				out.close();
			}
			if (in != null) {
				in.close();
			}
			if (fout != null) {
				fout.close();
			}
		}
	}
	
	/**
	 * 创建目录
	 * @param pathDir
	 */
	public static void createDirectory(String pathDir){
		File f = new File(pathDir);
		if (!f.exists()) {
			if (!f.mkdirs()) {
				log.error("檔夾創建失敗....");
				try {
					throw new Exception("檔夾創建失敗");
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
	/**
	 * 字符串截取工具
	 * @param subContext
	 * @param startIndex
	 * @param endIndex
	 * @return
	 */
	public static String subString(String subContext ,int startIndex, int endIndex){
		if(startIndex <= endIndex){
			if(0 == endIndex){
				return subContext.substring(startIndex);
			}else{
				return subContext.substring(startIndex ,endIndex);
			}
		}else{
			return subContext.substring(startIndex);
		}
	}
	
    /**
     * 刪除檔夾下所有內容，包括此檔夾
     * @param f
     * @throws IOException
     */
	public static void delAll(File f) throws Exception {
		if (f == null) {
			// throw new IOException("檔不能為空");
			return;
		}
		if (!f.exists()) {// 檔案夾不存在不存在
			// throw new IOException("指定目錄不存在:"+f.getName());
			return;
		}
		boolean result = true; // 保存中間結果
		if (!(result = f.delete())) {// 先嘗試直接刪除
		//若檔案夾非空,刪除內容
			File subs[] = f.listFiles();
			for (int i = 0; i <= subs.length - 1; i++) {
				if (subs[i].isDirectory())
					delAll(subs[i]);// 遞迴刪除子檔夾內容
				result = subs[i].delete();// 刪除子檔夾本身
			}
			result = f.delete();// 刪除此檔夾本身
		}
		if (!result)
			throw new IOException("無法刪除:" + f.getName());
	}
	
	

}
